{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "49e1c892",
   "metadata": {},
   "outputs": [],
   "source": [
    "from src.circuit import Adder, AdderRev, ModAdder, ModAdderRev\n",
    "from src.circuit import ModMulti7xmod15, ModExp\n",
    "from src.utils import c2q, q2c"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "c958e185-2b1c-48a0-8f0c-113d0d00eca2",
   "metadata": {},
   "source": [
    "## 加法器、减法器\n",
    "\n",
    "无符号4-bit加法器和减法器线路如下图所示。a3-a2-a1-a0 和 b3-b2-b1-b0 分别记作 a 和 b，则加法器计算 b + a， 减法器（逆加法器）计算 b - a. 最终的计算结果保存在 b 中。\n",
    "\n",
    "<img src=\"./images/Fig6_adder.jpg\" width=400>\n",
    "\n",
    "<img src=\"./images/Fig7_subtractor.jpg\" width=400>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "082ce15a-342d-4ba5-bfbf-41b4fd6aef27",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "验证加法器,减法器:\n",
      "ket string: 1¦0000010110011⟩\n",
      "ket string: 1¦0010001010011⟩\n",
      "q_add = 11, c_add = 11\n",
      "q_sub = 5, c_sub = 5\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def demo1():\n",
    "    \"\"\"验证 Fig.6（加法器）, Fig.7 （减法器）\n",
    "    \"\"\"\n",
    "    print(\"验证加法器,减法器:\")\n",
    "    # 验证 b + a, b - a\n",
    "    a = 3\n",
    "    b = 8\n",
    "    cir_a = c2q([3, 2, 1, 0], a)\n",
    "    cir_b = c2q([7, 6, 5, 4], b)\n",
    "\n",
    "    cir_add = cir_a + cir_b + Adder()\n",
    "    q_add = q2c(cir_add, [7, 6, 5, 4])\n",
    "\n",
    "    cir_sub = cir_a + cir_b + AdderRev()\n",
    "    q_sub = q2c(cir_sub, [7, 6, 5, 4])\n",
    "\n",
    "    print(\n",
    "        f\"q_add = {q_add}, c_add = {b + a}\\nq_sub = {q_sub}, c_sub = {b - a}\\n\")\n",
    "\n",
    "\n",
    "demo1()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fa4b9fb-7f59-46d3-a233-1564eff70063",
   "metadata": {},
   "source": [
    "打印的结果中， `q_` 开头代表量子计算的结果，`c_` 开头代表经典计算机或正确的结果，`add` 和 `sub` 分别代表加法器和减法器，`ket string` 是线路的终态。以 `a = 3, b = 8` 为例，量子线路结果正确。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "94b3042b-4696-479a-8d52-2d0da3c23a3b",
   "metadata": {},
   "source": [
    "## 模加法器、模减法器\n",
    "\n",
    "与加法器和减法器相比，引入模运算后会将加减的结果求模，结果保存在寄存器b中。Fig.8 和 Fig.9 中的最左和最右竖直灰色线条分割开输入和输出，中间是运算器主体部分。后文类似，不再赘述。\n",
    "\n",
    "<img src=\"./images/Fig8_modular_adder.jpg\" width=400>\n",
    "\n",
    "<img src=\"./images/Fig9_rev_modular_adder.jpg\" width=400>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e889f602-d31c-44d8-a7a0-6420cb197c02",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "验证模加法器、模减法器:\n",
      "ket string: 1¦000000000001011011⟩\n",
      "ket string: 1¦000000000011011011⟩\n",
      "q_add = 5, c_add = 5\n",
      "q_sub = 13, c_sub = 13\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def demo2():\n",
    "    \"\"\"验证模加法器、模减法器\n",
    "    \"\"\"\n",
    "    print(\"验证模加法器、模减法器:\")\n",
    "    # 1. 计算 (a + b) mod n\n",
    "    # 2. 计算 (b - a) mod n。注：对 b<a, (b-a) mod n = (b-a+n) mod n\n",
    "    a = 11\n",
    "    b = 9\n",
    "    n = 15\n",
    "    # 将经典数值转换成量子线路编码\n",
    "    cir_a = c2q([3, 2, 1, 0], a)\n",
    "    cir_b = c2q([7, 6, 5, 4], b)\n",
    "    cir_n = c2q([16, 15, 14, 13], n)  # 输入置1\n",
    "\n",
    "    cir_madd = cir_a + cir_b + cir_n + ModAdder() + cir_n\n",
    "    cir_msub = cir_a + cir_b + cir_n + ModAdderRev() + cir_n\n",
    "    # 使用量子线路计算结果\n",
    "    q_add = q2c(cir_madd, [7, 6, 5, 4])\n",
    "    q_sub = q2c(cir_msub, [7, 6, 5, 4])\n",
    "    # 经典计算验证\n",
    "    c_add = (a + b) % n\n",
    "    c_sub = (b - a) % n\n",
    "\n",
    "    print(\n",
    "        f\"q_add = {q_add}, c_add = {c_add}\\nq_sub = {q_sub}, c_sub = {c_sub}\\n\")\n",
    "\n",
    "demo2()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "344cfcac-7c6c-4736-85e5-069a274fd37d",
   "metadata": {},
   "source": [
    "## 模乘法器\n",
    "\n",
    "以 $7 x\\mod 15$ 为例，其线路如 Fig.10 所示。在 8U32G 硬件平台上，运行模乘法器耗时大约 20 秒。\n",
    "\n",
    "<img src=\"./images/Fig10_7xmod15.jpg\" width=400>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "5546d1d4-ca89-49c9-b4ea-8b08743e21fc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "验证模乘法器(8U32G硬件大约耗时20秒):\n",
      "ket string: 1¦00000000000011000010011⟩\n",
      "q_mul = 3, c_mul = 3\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def demo3():\n",
    "    \"\"\"验证模乘法器\n",
    "    \"\"\"\n",
    "    print(\"验证模乘法器(8U32G硬件大约耗时20秒):\")\n",
    "    # 计算 7x mod n\n",
    "    ctrl = 1  # 控制位\n",
    "    x = 9\n",
    "    n = 15\n",
    "    cir_ctrl = c2q([0], ctrl)\n",
    "    cir_x = c2q([4, 3, 2, 1], x)\n",
    "    cir_n = c2q([21, 20, 19, 18], n)\n",
    "    cir_7x = cir_ctrl + cir_x + cir_n + ModMulti7xmod15() + cir_n\n",
    "    # 获取终态得到结果\n",
    "    q_mul = q2c(cir_7x, [12, 11, 10, 9])\n",
    "    c_mul = (7 * x) % 15\n",
    "\n",
    "    print(f\"q_mul = {q_mul}, c_mul = {c_mul}\\n\")\n",
    "\n",
    "\n",
    "demo3()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "09b85e0a-5ad7-4a1c-ab14-681b3af36ddf",
   "metadata": {},
   "source": [
    "## 模指数器\n",
    "\n",
    "以 $7^3 \\mod 15$ 为例， 其线路如图 Fig.12 所示。在 8U32G 硬件平台上，运行模乘法器耗时大约 20 分钟。最终的结果存储在 `regx` 中。从运行结果可以看出，量子线路的计算结果正确。\n",
    "\n",
    "<img src=\"./images/Fig12_modular_exp.jpg\" width=600>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "0a2cfe1f-cb33-4da9-8058-70d09c29c529",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "验证模指数器(8U32G硬件大约耗时20分钟):\n",
      "ket string: 1¦000000000000000000110100011⟩\n",
      "q_res = 13, c_res = 13\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def demo4():\n",
    "    \"\"\"验证模指数器\n",
    "    \"\"\"\n",
    "    # 计算 7^a mod n\n",
    "    print(\"验证模指数器(8U32G硬件大约耗时20分钟):\")\n",
    "    a = 3\n",
    "    n = 15\n",
    "    cir_a = c2q([3, 2, 1, 0], a)\n",
    "    cir_n = c2q([25, 24, 23, 22], n)\n",
    "    cir_expmod = cir_a + cir_n + ModExp() + cir_n\n",
    "\n",
    "    q_res = q2c(cir_expmod, [8, 7, 6, 5])\n",
    "    c_res = (7**a) % n\n",
    "\n",
    "    print(f\"q_res = {q_res}, c_res = {c_res}\\n\")\n",
    "\n",
    "demo4()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "mindspore",
   "language": "python",
   "name": "mindspore"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
